import { useUIStore } from "@/store/uiStore";
import { useItemStore } from "@/store/itemStore";
import {
  getCellPosition,
  getGridIndex,
  getScreenSize,
  loadImage,
} from "@/utils";
import HotbarUI from "@/assets/images/inventory.png";
import PlacementTiles from "@/assets/images/tiles/buildingPlacementTiles.png";
import { checkCollision } from "@/utils/collision";
import { useCameraStore } from "@/store/cameraStore";
import { globalScale } from "@/config/static";

/**
 * 快捷操作栏UI
 */
export class HotBarUI {
  private uiStore = useUIStore();
  private itemStore = useItemStore();
  private itemImages: Record<string, HTMLImageElement> = {};
  private slots: {
    x: number;
    y: number;
    width: number;
    height: number;
    slotId: number;
  }[] = [];
  private slotCount = 12; // 快捷栏槽位数量
  private slotSize = 42; // 槽位大小
  private slotPadding = 6; // 槽位间距
  private barHeight = 72; // 快捷栏高度

  // 拖动相关属性
  private isDragging = false; // 是否正在拖动
  private draggedItemSlot: number | null = null; // 被拖动的物品槽位ID
  private dragPosition = { x: 0, y: 0 }; // 拖动位置

  // 放置提示相关
  private placementTilesImage: HTMLImageElement | null = null;
  private canPlace: boolean = false; // 是否可以放置物品
  private gridSize = 16;
  private snapPosition = { x: 0, y: 0 }; // 放置的位置

  constructor() {
    const { width: screenWidth, height: screenHeight } = getScreenSize();

    loadImage(HotbarUI).then((image) => {
      this.uiStore.registerElement("hotbar", {
        visible: true,
        zIndex: 21,
        resources: image,
        type: "hotbarUI",
        sourceRect: {
          x: 0,
          y: 452,
          width: 595,
          height: this.barHeight,
        },
        position: {
          x: screenWidth / 2 - 320,
          y: screenHeight / 2 + 300,
        },
        size: {
          width: 595,
          height: this.barHeight,
        },
      });
      this.initHotbarSlots();
      this.preloadItemImages();
    });

    loadImage(PlacementTiles).then((image) => {
      this.placementTilesImage = image;
    });
  }

  /**
   * 处理鼠标按下事件
   * @param event 鼠标事件
   */
  public handleMouseDown(event: MouseEvent) {
    const element = this.uiStore.uiElements["hotbar"];
    if (!element || !element.visible) return;

    // 获取鼠标位置
    const mouseX = event.clientX;
    const mouseY = event.clientY;

    for (const slot of this.slots) {
      if (
        mouseX >= slot.x &&
        mouseX <= slot.x + slot.width &&
        mouseY >= slot.y &&
        mouseY <= slot.y + slot.height
      ) {
        const inventorySlot = this.itemStore.inventory
          .filter((s) => s.type === "hotbar" && s.item)
          .find((s) => s.id === slot.slotId);

        if (inventorySlot && inventorySlot.item) {
          this.itemStore.selectedSlot = slot.slotId;

          if (inventorySlot.item.item.placeable) {
            this.isDragging = true;
            this.draggedItemSlot = slot.slotId;
            this.dragPosition = { x: mouseX, y: mouseY };
          }

          // 阻止事件冒泡和默认行为
          event.stopPropagation();
          event.preventDefault();
        }
      }
    }
  }

  /**
   * 鼠标移动事件
   * @param event 鼠标事件
   */
  public async handleMouseMove(event: MouseEvent) {
    if (!this.isDragging || !this.draggedItemSlot) return;

    this.dragPosition = { x: event.clientX, y: event.clientY };

    this.snapPosition = await getCellPosition(event.clientX, event.clientY);

    // console.log("this.snapPosition", this.snapPosition);

    // this.canPlace = this.checkCanPlace(
    //   this.snapPosition.x,
    //   this.snapPosition.y
    // );

    event.stopPropagation();
    event.preventDefault();
  }

  /**
   * 鼠标松开事件
   * @param event 鼠标事件
   */
  public handleMouseUp(event: MouseEvent) {
    if (!this.isDragging || this.draggedItemSlot === null) return;

    const inventorySlot = this.itemStore.inventory
      .filter((s) => s.type === "hotbar" && s.item)
      .find((s) => s.id === this.draggedItemSlot);

    // 先手动设置为true
    this.canPlace = true;

    if (
      inventorySlot &&
      inventorySlot.item &&
      inventorySlot.item.item.placeable
    ) {
      import("@/utils/furnitureManager").then(({ furniturePlacer }) => {
        if (this.canPlace && inventorySlot.item) {
          const cameraStore = useCameraStore();
          const cameraOffset = cameraStore.cameraOffset;

          const worldX = event.clientX / 3 + cameraOffset.x;
          const worldY = event.clientY / 3 + cameraOffset.y;

          const position = getGridIndex(worldX, worldY);

          furniturePlacer.placeFurniture(
            position.x * this.gridSize,
            position.y * this.gridSize,
            inventorySlot.item.item
          );
        }
      });
    }

    this.isDragging = false;
    this.draggedItemSlot = null;

    event.stopPropagation();
    event.preventDefault();
  }

  /**
   * 处理键盘按键事件
   * @param event 键盘事件
   */
  public handleKeyDown(event: KeyboardEvent) {
    const keyMap: { [key: string]: number } = {
      "1": 0,
      "2": 1,
      "3": 2,
      "4": 3,
      "5": 4,
      "6": 5,
      "7": 6,
      "8": 7,
      "9": 8,
      "0": 9,
      "-": 10,
      "=": 11,
    };

    const key = event.key;
    if (key in keyMap) {
      const slotId = keyMap[key];
      const inventorySlot = this.itemStore.inventory
        .filter((s) => s.type === "hotbar" && s.item)
        .find((s) => s.id === slotId);

      if (inventorySlot && inventorySlot.item) {
        this.itemStore.selectedSlot = slotId;

        // 阻止事件冒泡和默认行为
        event.stopPropagation();
        event.preventDefault();
      }
    }
  }

  /**
   * 检查是否可以放置物品
   * @param x 放置位置的x坐标
   * @param y 放置位置的y坐标
   */
  checkCanPlace(x: number, y: number): boolean {
    if (!this.draggedItemSlot) return false;

    const inventorySlot = this.itemStore.inventory
      .filter((s) => s.type === "hotbar" && s.item)
      .find((s) => s.id === this.draggedItemSlot);

    if (!inventorySlot || !inventorySlot.item) return false;

    const item = inventorySlot.item;
    const itemData = item.item;

    const drawWidth = itemData.sourceRect.drawWidth;
    const drawHeight = itemData.sourceRect.drawHeight;

    if (checkCollision(x, y, drawWidth, drawHeight, "item")) {
      return false;
    }

    return true;
  }

  /**
   * 预加载物品图片
   */
  private async preloadItemImages() {
    // 获取所有物品的图片URL
    const imageUrls = new Set<string>();

    this.itemStore.inventory.forEach((slot) => {
      if (slot.item) {
        imageUrls.add(slot.item.item.imageUrl);
      }
    });

    // 加载所有图片
    for (const url of imageUrls) {
      try {
        this.itemImages[url] = await loadImage(url);
      } catch (error) {
        console.error(`加载物品图片失败: ${url}`, error);
      }
    }
  }

  /**
   * 初始化快捷栏槽位
   */
  private initHotbarSlots() {
    const element = this.uiStore.uiElements["hotbar"];
    if (!element || !element.position) return;

    const startX = element.position.x + 13;
    const startY = element.position.y + 15;

    for (let i = 0; i < this.slotCount; i++) {
      this.slots.push({
        x: startX + i * (this.slotSize + this.slotPadding),
        y: startY,
        width: this.slotSize,
        height: this.slotSize,
        slotId: i,
      });
    }
  }

  /**
   * 渲染槽位
   * @param ctx 画布上下文
   */
  private renderSlots(ctx: CanvasRenderingContext2D) {
    if (!ctx) return;

    const keyLabels = [
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "0",
      "-",
      "=",
    ];

    for (const slot of this.slots) {
      // 检查是否是当前选中的槽位
      if (slot.slotId === this.itemStore.selectedSlot) {
        // 绘制红色边框
        ctx.strokeStyle = "#ff0000"; // 红色
        ctx.lineWidth = 2; // 稍微粗一点的线宽
      } else {
        // 其他槽位使用默认边框样式
        ctx.strokeStyle = "rgba(0, 0, 0, 0)";
        ctx.lineWidth = 2;
      }

      ctx.strokeRect(slot.x, slot.y, slot.width, slot.height);

      if (slot.slotId < keyLabels.length) {
        // 这里要保存当前状态，否则会影响到其他绘制
        ctx.save();
        ctx.font = "12px Arial";
        ctx.fillStyle = "#fff";
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";
        ctx.fillText(keyLabels[slot.slotId], slot.x + 5, slot.y + 5);
        ctx.shadowColor = "rgba(0, 0, 0, 0.7)";
        ctx.shadowBlur = 2;
        ctx.shadowOffsetX = 1;
        ctx.shadowOffsetY = 1;
        ctx.restore();
      }
    }
  }

  /**
   * 渲染快捷栏UI
   * @param ctx 画布上下文
   */
  render(ctx: CanvasRenderingContext2D) {
    if (!ctx) return;

    const uiElements = this.uiStore.uiElements;
    const element = uiElements["hotbar"];

    if (!element || !element.visible) return;

    if (
      element.resources &&
      element.sourceRect &&
      element.position &&
      element.size
    ) {
      const destX = Math.floor(element.position.x);
      const destY = Math.floor(element.position.y);
      const destWidth = Math.floor(element.size.width);
      const destHeight = Math.floor(element.size.height);

      ctx.drawImage(
        element.resources,
        element.sourceRect.x,
        element.sourceRect.y,
        element.sourceRect.width,
        element.sourceRect.height,
        destX,
        destY,
        destWidth,
        destHeight
      );
    }
    this.renderSlots(ctx);
    this.renderItems(ctx);

    if (this.isDragging) {
      this.renderSnappedItem(ctx);
      this.renderDraggedItem(ctx);
    }
  }

  /**
   * 渲染物品
   * @param ctx 画布上下文
   */
  private renderItems(ctx: CanvasRenderingContext2D) {
    if (!ctx) return;

    for (const slot of this.slots) {
      const inventorySlot = this.itemStore.inventory
        .filter((s) => s.type === "hotbar" && s.item)
        .find((s) => s.id === slot.slotId);

      if (!inventorySlot || !inventorySlot.item) continue;

      const item = inventorySlot.item;
      const itemData = item.item;
      const image = this.itemImages[itemData.imageUrl];

      if (!image) continue;

      // 绘制物品图标
      const drawWidth = itemData.sourceRect.drawWidth;
      const drawHeight = itemData.sourceRect.drawHeight;
      const iconX =
        slot.x +
        itemData.sourceRect.offsetX +
        this.slotSize / 2 -
        drawWidth / 2;
      const iconY =
        slot.y +
        itemData.sourceRect.offsetY +
        this.slotSize / 2 -
        drawHeight / 2;

      ctx.drawImage(
        image,
        itemData.sourceRect.x,
        itemData.sourceRect.y,
        itemData.sourceRect.width,
        itemData.sourceRect.height,
        iconX,
        iconY,
        drawWidth,
        drawHeight
      );
    }
  }

  /**
   * 渲染被拖动的物品
   * @param ctx 画布上下文
   */
  private renderDraggedItem(ctx: CanvasRenderingContext2D) {
    if (!ctx || !this.isDragging || this.draggedItemSlot === null) return;

    const inventorySlot = this.itemStore.inventory
      .filter((s) => s.type === "hotbar" && s.item)
      .find((s) => s.id === this.draggedItemSlot);

    if (!inventorySlot || !inventorySlot.item) return;

    const item = inventorySlot.item;
    const itemData = item.item;
    const image = this.itemImages[itemData.imageUrl];

    if (!image) return;

    const drawWidth = itemData.sourceRect.drawWidth;
    const drawHeight = itemData.sourceRect.drawHeight;
    const iconX = this.dragPosition.x + drawWidth / 2;
    const iconY = this.dragPosition.y + drawHeight / 2;

    ctx.drawImage(
      image,
      itemData.sourceRect.x,
      itemData.sourceRect.y,
      itemData.sourceRect.width,
      itemData.sourceRect.height,
      iconX,
      iconY,
      drawWidth,
      drawHeight
    );
  }

  /**
   * 渲染放置物品的位置
   * @param ctx 画布上下文
   */
  private renderSnappedItem(ctx: CanvasRenderingContext2D) {
    if (!ctx || !this.isDragging || this.draggedItemSlot === null) return;

    const inventorySlot = this.itemStore.inventory
      .filter((s) => s.type === "hotbar" && s.item)
      .find((s) => s.id === this.draggedItemSlot);

    if (!inventorySlot || !inventorySlot.item) return;

    const item = inventorySlot.item;
    const itemData = item.item;
    const image = this.itemImages[itemData.imageUrl];

    if (!image) return;

    // 原始尺寸
    const drawWidth = itemData.sourceRect.drawWidth;
    const drawHeight = itemData.sourceRect.drawHeight;

    // 放大系数
    const scale = globalScale;

    // 放大后的尺寸
    const enlargedWidth = drawWidth * scale;
    const enlargedHeight = drawHeight * scale;

    ctx.save();
    // 根据是否可放置设置透明度
    ctx.globalAlpha = this.canPlace ? 0.5 : 0.3;

    ctx.drawImage(
      image,
      itemData.sourceRect.x,
      itemData.sourceRect.y,
      itemData.sourceRect.width,
      itemData.sourceRect.height,
      this.snapPosition.x,
      // 如果有offsetY，则需要调整物品的垂直位置
      itemData.sourceRect.dragOffsetY !== 0
        ? this.snapPosition.y -
            itemData.sourceRect.height -
            itemData.sourceRect.dragOffsetY
        : this.snapPosition.y,
      enlargedWidth,
      enlargedHeight
    );
    ctx.restore();
  }

  /**
   * 显示或隐藏
   */
  toggle() {
    const element = this.uiStore.uiElements["hotbar"];
    if (element) {
      element.visible = !element.visible;
    }
  }
}
